home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / POSTSCPT / GSVIEW / SRC / GVPPRN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-30  |  31.0 KB  |  949 lines

  1. /* Copyright (C) 1993, 1994, Russell Lang.  All rights reserved.
  2.   
  3.   This file is part of GSview.
  4.   
  5.   This program is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the GSview Free Public Licence 
  9.   (the "Licence") for full details.
  10.   
  11.   Every copy of GSview must include a copy of the Licence, normally in a 
  12.   plain ASCII text file named LICENCE.  The Licence grants you the right 
  13.   to copy, modify and redistribute GSview, but only under certain conditions 
  14.   described in the Licence.  Among other things, the Licence requires that 
  15.   the copyright notice and this notice be preserved on all copies.
  16. */
  17.  
  18. /* gvpprn.c */
  19. /* Printer routines for PM GSview */
  20. #include "gvpm.h"
  21.  
  22. #ifndef UNUSED
  23. void gs_prn_process(void);
  24. #endif
  25.  
  26. char not_defined[] = "[Not defined]";
  27.  
  28. #define PRINT_BUF_SIZE 16384u
  29.  
  30. MRESULT EXPENTRY
  31. SpoolDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  32. {
  33. int notify_message;
  34. int i, j;
  35. char *entry;
  36.     switch(msg) {
  37.       case WM_INITDLG:
  38.     entry = (char *)mp2;
  39.     j = 0;
  40.     i = 0;
  41.     while (*entry) {
  42.         if ( strcmp(entry, option.printer_port) == 0 )
  43.         j = i;
  44.         entry += strlen(entry)+1; /* skip to queue comment */
  45.         if (*entry) {
  46.             WinSendMsg( WinWindowFromID(hwnd, SPOOL_PORT),
  47.                 LM_INSERTITEM, MPFROMLONG(LIT_END), MPFROMP(entry));
  48.             entry += strlen(entry)+1;
  49.         }
  50.         i++;
  51.     }
  52.     WinSendMsg( WinWindowFromID(hwnd, SPOOL_PORT),
  53.             LM_SELECTITEM, MPFROMLONG(j), MPFROMLONG(TRUE) );
  54.     break;
  55.     case WM_CONTROL:
  56.     notify_message = SHORT2FROMMP(mp1);
  57.     switch (notify_message) {
  58.         case LN_ENTER:
  59.             if (SHORT1FROMMP(mp1) == SPOOL_PORT)
  60.             WinPostMsg(hwnd, WM_COMMAND, (MPARAM)DID_OK, MPFROM2SHORT(CMDSRC_OTHER, TRUE));
  61.         break;
  62.     }
  63.     break;
  64.     case  WM_COMMAND:
  65.       switch(LOUSHORT(mp1)) {
  66.     case ID_HELP:
  67.         get_help();
  68.         return (MRESULT)TRUE;
  69.         case DID_OK:
  70.         WinDismissDlg(hwnd, 1+(int)WinSendMsg(WinWindowFromID(hwnd, SPOOL_PORT), 
  71.         LM_QUERYSELECTION, (MPARAM)0, (MPARAM)0));
  72.             return (MRESULT)TRUE;
  73.     case DID_CANCEL:
  74.         WinDismissDlg(hwnd, 0);
  75.         return (MRESULT)TRUE;
  76.       }
  77.       break;
  78.     }
  79.     return WinDefDlgProc(hwnd, msg, mp1, mp2);
  80. }
  81.  
  82. char *
  83. get_ports(char *buf, int len)
  84. {
  85. /* get port list from SplEnumQueue */
  86. /* port list consists of entries formatted as follows */
  87. /*    queue_name,'\0',queue_comment,'\0' */
  88. /* terminated by double null */
  89. /* We need to use queue_name, user needs to see queue_comment */
  90.  
  91.     SPLERR splerr;
  92.     USHORT jobCount ;
  93.     ULONG  cbBuf ;
  94.     ULONG  cTotal;
  95.     ULONG  cReturned ;
  96.     ULONG  cbNeeded ;
  97.     ULONG  ulLevel ;
  98.     ULONG  i ;
  99.     PSZ    pszComputerName ;
  100.     PBYTE  pBuf ;
  101.     PPRQINFO3 prq ;
  102.     int used;
  103.     char *p;
  104.  
  105.     used = 0;
  106.     p = buf;
  107.     ulLevel = 3L;
  108.     pszComputerName = (PSZ)NULL ;
  109.     splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, 0L, /* cbBuf */
  110.                           &cReturned, &cTotal,
  111.                           &cbNeeded, NULL);
  112.     if ( splerr == ERROR_MORE_DATA || splerr == NERR_BufTooSmall ) {
  113.        if (!DosAllocMem( (PVOID)&pBuf, cbNeeded,
  114.                          PAG_READ|PAG_WRITE|PAG_COMMIT) ) {
  115.           cbBuf = cbNeeded ;
  116.           splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, cbBuf,
  117.                                   &cReturned, &cTotal,
  118.                                   &cbNeeded, NULL);
  119.           if (splerr == NO_ERROR) {
  120.              /* Set pointer to point to the beginning of the buffer.           */
  121.              prq = (PPRQINFO3)pBuf;
  122.  
  123.              /* cReturned has the count of the number of PRQINFO3 structures.  */
  124.              for (i=0;i < cReturned ; i++) {
  125.         used += strlen(prq->pszName) + 1;
  126.         used += strlen(prq->pszComment) + 1;
  127.         if (used < len) {
  128.             strcpy(p, prq->pszName);
  129.             p += strlen(p)+1;
  130.             strcpy(p, prq->pszComment);
  131.             p += strlen(p)+1;
  132.         }
  133.                 prq++;
  134.              }/*endfor cReturned */
  135.           }
  136.           DosFreeMem((PVOID)pBuf) ;
  137.        }
  138.     } /* end if Q level given */
  139.     else {
  140.     *p++ = '\0';
  141.         *p = '\0';
  142.     return NULL;
  143.     }
  144.     *p = '\0';
  145.     return buf;
  146. }
  147.  
  148.  
  149. /* return TRUE if portname available */
  150. /* return FALSE if cancelled or error */
  151. /* if port non-NULL, use as suggested port */
  152. BOOL
  153. get_portname(char *portname, char *port)
  154. {
  155. char *buffer;
  156. char *p;
  157. int i, iport;
  158.     if ((buffer = malloc(PRINT_BUF_SIZE)) == (char *)NULL)
  159.         return FALSE;
  160.     /* get list of ports */
  161.     get_ports(buffer, PRINT_BUF_SIZE);
  162.     if (port != (char *)NULL) {
  163.         /* use specified port */
  164.         p = buffer;
  165.         while (strlen(p) != 0) {
  166.         if (strcmp(p, port)==0)
  167.             break;
  168.         p += strlen(p)+1;    /* skip queue name */
  169.         if (*p)
  170.             p += strlen(p)+1;    /* skip queue comment */
  171.         }
  172.         if (*p) {
  173.         strcpy(portname, "\\\\spool\\");
  174.         strcat(portname, p);
  175.         strcpy(option.printer_port, p);
  176.         }
  177.         else
  178.             port = NULL;    /* couldn't find it, so prompt for valid port */
  179.     }
  180.     if (port == (char *)NULL) {
  181.         /* select a port */
  182.         load_string(IDS_TOPICSPOOL, szHelpTopic, sizeof(szHelpTopic));
  183.         iport = WinDlgBox(HWND_DESKTOP, hwnd_frame, SpoolDlgProc, 0, IDD_SPOOL, buffer);
  184.         if (!iport || iport == 65536) {
  185.         free(buffer);
  186.         return FALSE;
  187.         }
  188.         p = buffer;
  189.         for (i=2; i<iport+iport && strlen(p)!=0; i++)
  190.         p += strlen(p)+1;
  191.         strcpy(portname, "\\\\spool\\");
  192.         strcat(portname, p);
  193.         strcpy(option.printer_port, p);
  194.     }
  195.  
  196.     if (strlen(portname) == 0)
  197.         return FALSE;
  198.     free(buffer);
  199.     return TRUE;
  200. }
  201.  
  202. /* If strlen(queue_name)==0, return default queue and driver name */
  203. /* If queue_name supplied, return driver_name */
  204. /* returns 0 if OK, non-zero for error */
  205. int
  206. spl_find_queue(char *queue_name, char *driver_name)
  207. {
  208.     SPLERR splerr;
  209.     USHORT jobCount;
  210.     ULONG  cbBuf;
  211.     ULONG  cTotal;
  212.     ULONG  cReturned;
  213.     ULONG  cbNeeded;
  214.     ULONG  ulLevel;
  215.     ULONG  i;
  216.     PSZ    pszComputerName;
  217.     PBYTE  pBuf;
  218.     PPRQINFO3 prq;
  219.  
  220.     ulLevel = 3L;
  221.     pszComputerName = (PSZ)NULL ;
  222.     splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, 0L, /* cbBuf */
  223.                           &cReturned, &cTotal,
  224.                           &cbNeeded, NULL);
  225.     if ( splerr == ERROR_MORE_DATA || splerr == NERR_BufTooSmall ) {
  226.        if (!DosAllocMem( (PVOID)&pBuf, cbNeeded,
  227.                          PAG_READ|PAG_WRITE|PAG_COMMIT) ) {
  228.           cbBuf = cbNeeded ;
  229.           splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, cbBuf,
  230.                                   &cReturned, &cTotal,
  231.                                   &cbNeeded, NULL);
  232.           if (splerr == NO_ERROR) {
  233.              /* Set pointer to point to the beginning of the buffer.           */
  234.              prq = (PPRQINFO3)pBuf ;
  235.  
  236.              /* cReturned has the count of the number of PRQINFO3 structures.  */
  237.              for (i=0;i < cReturned ; i++) {
  238.             /* find queue name and return driver name */
  239.             if (strlen(queue_name)==0) {  /* use default queue */
  240.                 if ( prq->fsType & PRQ3_TYPE_APPDEFAULT )
  241.                 strcpy(queue_name, prq->pszName);
  242.             }
  243.             if (strcmp(prq->pszName, queue_name) == 0) {
  244.             char *p;
  245.             for (p=prq->pszDriverName; *p && (*p!='.'); p++)
  246.                 /* do nothing */ ;
  247.             *p = '\0';  /* truncate at '.' */
  248.             if (driver_name != NULL)
  249.                 strcpy(driver_name, prq->pszDriverName);
  250.             DosFreeMem((PVOID)pBuf) ;
  251.             return 0;
  252.             }
  253.                 prq++;
  254.              }/*endfor cReturned */
  255.           }
  256.           DosFreeMem((PVOID)pBuf) ;
  257.        }
  258.     } /* end if Q level given */
  259.     else {
  260.        /* If we are here we had a bad error code. Print it and some other info.*/
  261.        gserror(0, "SplEnumQueue failed", MB_ICONEXCLAMATION, SOUND_ERROR);
  262.     }
  263.     if (splerr)
  264.         return splerr;
  265.     return -1;
  266. }
  267.  
  268.  
  269. /* Spool file to queue */
  270. /* queue==NULL means prompt for port with dialog box */
  271. /* return TRUE if successful, FALSE if error */
  272. int
  273. gp_printfile(char *filename, char *queue)
  274. {
  275. HSPL hspl;
  276. PDEVOPENSTRUC pdata;
  277. PSZ  pszToken = "*";
  278. ULONG jobid;
  279. BOOL rc;
  280. char queue_name[256];
  281. char driver_name[256];
  282. char port_name[256];
  283. char *buffer;
  284. FILE *f;
  285. int count;
  286.     if (!get_portname(port_name, queue))
  287.     return FALSE;
  288.     strcpy(queue_name, port_name+8);    /* ignore \\spool\ prefix */
  289.     spl_find_queue(queue_name, driver_name);
  290.  
  291.     if ((buffer = malloc(PRINT_BUF_SIZE)) == (char *)NULL) {
  292.     gserror(0, "Out of memory in gp_printfile", MB_ICONEXCLAMATION, SOUND_ERROR);
  293.     return FALSE;
  294.     }
  295.     if ((f = fopen(filename, "rb")) == (FILE *)NULL) {
  296.     gserror(IDS_NOTEMP, NULL, MB_ICONEXCLAMATION, SOUND_ERROR);
  297.     free(buffer);
  298.     return FALSE;
  299.     }
  300.  
  301.     /* Allocate memory for pdata */
  302.     if ( !DosAllocMem( (PVOID)&pdata,sizeof( DEVOPENSTRUC ),
  303.          (PAG_READ|PAG_WRITE|PAG_COMMIT ) ) ) {
  304.         /* Initialize elements of pdata */
  305.         pdata->pszLogAddress      = queue_name;
  306.         pdata->pszDriverName      = driver_name;
  307.         pdata->pdriv              = NULL;
  308.         pdata->pszDataType        = "PM_Q_RAW";
  309.         pdata->pszComment         = "GSview";
  310.         pdata->pszQueueProcName   = NULL;
  311.         pdata->pszQueueProcParams = NULL;
  312.         pdata->pszSpoolerParams   = NULL;
  313.         pdata->pszNetworkParams   = NULL;
  314.  
  315.         hspl = SplQmOpen( pszToken,5L,( PQMOPENDATA )pdata );
  316.         if ( hspl == SPL_ERROR ) {
  317.         gserror(0, "SplQMOpen failed", MB_ICONEXCLAMATION, SOUND_ERROR);
  318.         DosFreeMem((PVOID)pdata);
  319.         free(buffer);
  320.         fclose(f);
  321.         return FALSE;    /* failed */
  322.         }
  323.  
  324.     rc = SplQmStartDoc(hspl, filename);
  325.     if (!rc) {
  326.         gserror(0, "SplQMStartDoc failed", MB_ICONEXCLAMATION, SOUND_ERROR);
  327.         DosFreeMem((PVOID)pdata);
  328.         free(buffer);
  329.         fclose(f);
  330.         return FALSE;
  331.     }
  332.     
  333.     /* loop, copying file to queue */
  334.     while (rc && (count = fread(buffer, 1, PRINT_BUF_SIZE, f)) != 0 ) {
  335.         rc = SplQmWrite(hspl, count, buffer);
  336.         if (!rc)
  337.             gserror(0, "SplQMWrite failed", MB_ICONEXCLAMATION, SOUND_ERROR);
  338.       }
  339.     free(buffer);
  340.     fclose(f);
  341.  
  342.     if (!rc) {
  343.       gserror(0, "Aborting Spooling", MB_ICONEXCLAMATION, SOUND_ERROR);
  344.           SplQmAbort(hspl);
  345.         }
  346.     else {
  347.         SplQmEndDoc(hspl);
  348.         rc = SplQmClose(hspl);
  349.         if (!rc)
  350.             gserror(0, "SplQMClose failed", MB_ICONEXCLAMATION, SOUND_ERROR);
  351.     }
  352.     }
  353.     else
  354.     rc = FALSE;    /* no memory */
  355.     return rc;
  356. }
  357.  
  358.  
  359. void
  360. strip_spaces(char *s)
  361. {
  362. char *d = s;
  363.    while (*s) {
  364.     if (*s != ' ')
  365.         *d++ = *s;
  366.     s++;
  367.    }
  368.    *d = '\0';
  369. }
  370.  
  371. char editpropname[MAXSTR];
  372.  
  373. /* dialog for adding for editing properties */
  374. MRESULT EXPENTRY
  375. EditPropDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  376. {
  377. static char device[MAXSTR];
  378.     switch (msg) {
  379.       case WM_INITDLG:
  380.     strcpy(device, mp2);    /* initialise device name */
  381.     WinSendMsg( WinWindowFromID(hwnd, EDITPROP_NAME),
  382.         EM_SETTEXTLIMIT, MPFROM2SHORT(MAXSTR, 0), MPFROMLONG(0) );
  383.     WinSendMsg( WinWindowFromID(hwnd, EDITPROP_VALUE),
  384.         EM_SETTEXTLIMIT, MPFROM2SHORT(MAXSTR, 0), MPFROMLONG(0) );
  385.     if (*editpropname) {
  386.       PROFILE *prf;
  387.       char section[MAXSTR];
  388.       char buf[MAXSTR];
  389.       if ( (prf = profile_open(szIniFile)) != (PROFILE *)NULL ) {
  390.         if (*editpropname == 's')
  391.         WinSendMsg( WinWindowFromID(hwnd, EDITPROP_STRING),
  392.             BM_SETCHECK, MPFROMSHORT(1), MPFROMLONG(0));
  393.         else
  394.         WinSendMsg( WinWindowFromID(hwnd, EDITPROP_NUMBER),
  395.             BM_SETCHECK, MPFROMSHORT(1), MPFROMLONG(0));
  396.         WinSetWindowText(WinWindowFromID(hwnd, EDITPROP_NAME), editpropname+1);
  397.         strcpy(section, device);
  398.         strcat(section, " values");
  399.         profile_read_string(prf, section, editpropname, "", buf, sizeof(buf)-2);
  400.         WinSetWindowText(WinWindowFromID(hwnd, EDITPROP_VALUE), buf);
  401.         profile_close(prf);
  402.       }
  403.     }
  404.     else {
  405.         WinSendMsg( WinWindowFromID(hwnd, EDITPROP_NUMBER),
  406.             BM_SETCHECK, MPFROMSHORT(1), MPFROMLONG(0));
  407.     }
  408.     break;
  409.       case WM_CONTROL:
  410.     break;
  411.       case WM_COMMAND:
  412.     switch(LOUSHORT(mp1)) {
  413.         case ID_HELP:
  414.         get_help();
  415.         return (MRESULT)TRUE;
  416.         case EDITPROP_DEL:
  417.             {PROFILE *prf;
  418. /* need to reopen profile file - this is wasteful */
  419.           if ( (prf = profile_open(szIniFile)) != (PROFILE *)NULL ) {
  420.             char name[MAXSTR];
  421.             char section[MAXSTR];
  422.             if (WinSendMsg(WinWindowFromID(hwnd, EDITPROP_STRING), BM_QUERYCHECK,  
  423.             MPFROMLONG(0), MPFROMLONG(0)) > 0) {
  424.             strcpy(name, "s");
  425.             }
  426.             else
  427.             strcpy(name, "d");
  428.                 WinQueryWindowText(WinWindowFromID(hwnd, EDITPROP_NAME), sizeof(name)-2, name+1);
  429.             strip_spaces(name);
  430.             if (strlen(name)>1) {
  431.             strcpy(section, device);
  432.             strcat(section, " values");
  433.             profile_write_string(prf, section, name, NULL);
  434.             profile_write_string(prf, device, name, NULL);
  435.             }
  436.             profile_close(prf);
  437.           }
  438.         }
  439.         WinDismissDlg(hwnd, DID_OK);
  440.                 return (MRESULT)TRUE;
  441.         case DID_OK:
  442.             {PROFILE *prf;
  443. /* need to reopen profile file - this is wasteful */
  444.           if ( (prf = profile_open(szIniFile)) != (PROFILE *)NULL ) {
  445.             char name[MAXSTR];
  446.             char value[MAXSTR];
  447.             char section[MAXSTR];
  448.             if (WinSendMsg(WinWindowFromID(hwnd, EDITPROP_STRING), BM_QUERYCHECK,  
  449.             MPFROMLONG(0), MPFROMLONG(0)) > 0) {
  450.             strcpy(name, "s");
  451.             }
  452.             else
  453.             strcpy(name, "d");
  454.                 WinQueryWindowText(WinWindowFromID(hwnd, EDITPROP_NAME), sizeof(name)-2, name+1);
  455.                 WinQueryWindowText(WinWindowFromID(hwnd, EDITPROP_VALUE), sizeof(value), value);
  456.             strip_spaces(name);
  457.             strip_spaces(value);
  458.             if ((strlen(name)>1) && strlen(value)) {
  459.             strcpy(section, device);
  460.             strcat(section, " values");
  461.             profile_write_string(prf, section, name, value);
  462.             strtok(value, ",");
  463.             profile_write_string(prf, device, name, value);
  464.             }
  465.             profile_close(prf);
  466.           }
  467.         }
  468.         WinDismissDlg(hwnd, DID_OK);
  469.                 return (MRESULT)TRUE;
  470.         case DID_CANCEL:
  471.         WinDismissDlg(hwnd, DID_CANCEL);
  472.         return (MRESULT)TRUE;
  473.     }
  474.     break;
  475.     }
  476.     return WinDefDlgProc(hwnd, msg, mp1, mp2);
  477. }
  478.  
  479.  
  480. /* dialog box for selecting printer properties */
  481. MRESULT EXPENTRY
  482. PropDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  483. {
  484.     char buf[128];
  485.     int iprop;
  486.     int ivalue;
  487.     char *p;
  488.     char *value;
  489.     static char device[MAXSTR];    /* contains printer device name */
  490.     static struct prop_item_s* propitem;
  491.     char section[MAXSTR];
  492.  
  493.     switch (msg) {
  494.       case WM_INITDLG:
  495.     strcpy(device, mp2);    /* initialise device name */
  496.     propitem = get_properties(device);
  497.     if (propitem == (struct prop_item_s *)NULL) {
  498.         WinDismissDlg(hwnd, FALSE);
  499.         return (MRESULT)TRUE;
  500.     }
  501.     WinSendMsg(WinWindowFromID(hwnd, PROP_NAME), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
  502.     WinSendMsg(WinWindowFromID(hwnd, PROP_VALUE), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
  503.     WinSetWindowText(WinWindowFromID(hwnd, PROP_NAME), "");
  504.     WinSetWindowText(WinWindowFromID(hwnd, PROP_VALUE), "");
  505.     for (iprop=0; propitem[iprop].name[0]; iprop++) {
  506.         WinSendMsg( WinWindowFromID(hwnd, PROP_NAME),
  507.             LM_INSERTITEM, MPFROMLONG(LIT_END), MPFROMP(propitem[iprop].name+1));
  508.     }
  509.         WinEnableWindow(WinWindowFromID(hwnd, PROP_NAME), (iprop != 0));
  510.         WinEnableWindow(WinWindowFromID(hwnd, PROP_VALUE), (iprop != 0));
  511.         WinEnableWindow(WinWindowFromID(hwnd, PROP_EDIT), (iprop != 0));
  512.  
  513.     WinSendMsg( WinWindowFromID(hwnd, PROP_NAME),
  514.             LM_SELECTITEM, MPFROMLONG(0), MPFROMLONG(TRUE) );
  515. /*
  516.     WinSendMsg(hwnd, WM_CONTROL, MPFROM2SHORT(PROP_NAME, CBN_LBSELECT),
  517.             MPFROMLONG(WinWindowFromID(hwnd, PROP_NAME)));
  518. */
  519.     if (option.gsversion < IDM_GS351) {
  520.           WinEnableWindow(WinWindowFromID(hwnd, PROP_XOFFSET), FALSE);
  521.           WinEnableWindow(WinWindowFromID(hwnd, PROP_YOFFSET), FALSE);
  522.     }
  523.     else {
  524.         PROFILE *prf;
  525.         strcpy(section, device);
  526.         strcat(section, " PageOffset");
  527.   /* need to reopen profile file - this is wasteful */
  528.         if ( (prf = profile_open(szIniFile)) != (PROFILE *)NULL ) {
  529.         profile_read_string(prf, section, "X", "0", buf, sizeof(buf)-2);
  530.             WinSendMsg( WinWindowFromID(hwnd, PROP_XOFFSET),
  531.                 EM_SETTEXTLIMIT, MPFROM2SHORT(sizeof(buf)-2, 0), MPFROMLONG(0) );
  532.         WinSetWindowText(WinWindowFromID(hwnd, PROP_XOFFSET), buf);
  533.         profile_read_string(prf, section, "Y", "0", buf, sizeof(buf)-2);
  534.             WinSendMsg( WinWindowFromID(hwnd, PROP_YOFFSET),
  535.                 EM_SETTEXTLIMIT, MPFROM2SHORT(sizeof(buf)-2, 0), MPFROMLONG(0) );
  536.         WinSetWindowText(WinWindowFromID(hwnd, PROP_YOFFSET), buf);
  537.         profile_close(prf);
  538.         }
  539.     }
  540.     break;
  541.       case WM_CONTROL:
  542.     if (mp1 == MPFROM2SHORT(PROP_NAME, CBN_LBSELECT)) {
  543.         iprop = (int)WinSendMsg(WinWindowFromID(hwnd, PROP_NAME), LM_QUERYSELECTION, (MPARAM)0, (MPARAM)0);
  544.         if (iprop == LIT_NONE)
  545.             return FALSE;
  546.         /* now look up entry in gsview.ini */
  547.         /* and update PROP_VALUE list box */
  548.         strcpy(section, device);
  549.         strcat(section, " values");
  550.         {PROFILE *prf;
  551. /* need to reopen profile file - this is wasteful */
  552.         if ( (prf = profile_open(szIniFile)) != (PROFILE *)NULL ) {
  553.                 profile_read_string(prf, section, propitem[iprop].name, "", buf, sizeof(buf)-2);
  554.             profile_close(prf);
  555.         }
  556.         else
  557.             buf[0] = '\0';
  558.         }
  559.         while ((*buf) && (buf[strlen(buf)-1]==' '))
  560.         buf[strlen(buf)-1] = '\0';    /* remove trailing spaces */
  561.         buf[strlen(buf)+1] = '\0';    /* put double NULL at end */
  562.         WinSendMsg(WinWindowFromID(hwnd, PROP_VALUE), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
  563.         WinSendMsg( WinWindowFromID(hwnd, PROP_VALUE),
  564.                     LM_INSERTITEM, MPFROMLONG(LIT_END), MPFROMP(not_defined) );
  565.         p = buf;
  566.         if (*p != '\0') {
  567.           WinEnableWindow(WinWindowFromID(hwnd, PROP_VALUE), TRUE);
  568.           while (*p!='\0') {
  569.         value = p;
  570.         while ((*p!='\0') && (*p!=','))
  571.             p++;
  572.         *p++ = '\0';
  573.             WinSendMsg( WinWindowFromID(hwnd, PROP_VALUE),
  574.                     LM_INSERTITEM, MPFROMLONG(LIT_END), MPFROMP(value) );
  575.           }
  576.         }
  577.         iprop = (int)WinSendMsg( WinWindowFromID(hwnd, PROP_VALUE),
  578.                 LM_SEARCHSTRING, MPFROM2SHORT(LSS_CASESENSITIVE, LIT_FIRST),
  579.             MPFROMP(propitem[iprop].value) );
  580.         if ((iprop == LIT_ERROR) || (iprop == LIT_NONE)) {
  581.         iprop = 0;
  582.             WinSetWindowText( WinWindowFromID(hwnd, PROP_VALUE), propitem[iprop].value);
  583.         }
  584.         else {
  585.         WinSendMsg( WinWindowFromID(hwnd, PROP_VALUE),
  586.             LM_SELECTITEM, MPFROMLONG(iprop), MPFROMLONG(TRUE) );
  587.         }
  588.     }
  589.     if (mp1 == MPFROM2SHORT(PROP_VALUE, CBN_LBSELECT)) {
  590.         iprop = (int)WinSendMsg(WinWindowFromID(hwnd, PROP_NAME), LM_QUERYSELECTION, (MPARAM)0, (MPARAM)0);
  591.         if (iprop == LIT_NONE)
  592.             return FALSE;
  593.         ivalue = (int)WinSendMsg(WinWindowFromID(hwnd, PROP_VALUE), LM_QUERYSELECTION, (MPARAM)0, (MPARAM)0);
  594.         if (ivalue == LIT_NONE)
  595.             return FALSE;
  596.         WinSendMsg(WinWindowFromID(hwnd, PROP_VALUE), LM_QUERYITEMTEXT,  
  597.         MPFROM2SHORT(ivalue, sizeof(propitem->value)), 
  598.         MPFROMP(propitem[iprop].value));
  599.     }
  600.     if (mp1 == MPFROM2SHORT(PROP_VALUE, CBN_EFCHANGE)) {
  601.         iprop = (int)WinSendMsg(WinWindowFromID(hwnd, PROP_NAME), LM_QUERYSELECTION, (MPARAM)0, (MPARAM)0);
  602.         if (iprop == LIT_NONE)
  603.             return FALSE;
  604.         WinQueryWindowText(WinWindowFromID(hwnd, PROP_VALUE), 
  605.              sizeof(propitem->value), propitem[iprop].value);
  606.     }
  607.     break;
  608.     case WM_COMMAND:
  609.     switch(LOUSHORT(mp1)) {
  610.         case PROP_EDIT:
  611.             load_string(IDS_TOPICEDITPROP, szHelpTopic, sizeof(szHelpTopic));
  612.             iprop = (int)WinSendMsg(WinWindowFromID(hwnd, PROP_NAME), LM_QUERYSELECTION, (MPARAM)0, (MPARAM)0);
  613.         editpropname[0] = '\0';
  614.         if (iprop != LIT_NONE)
  615.             strcpy(editpropname, propitem[iprop].name);
  616.         WinDlgBox(HWND_DESKTOP, hwnd, EditPropDlgProc, 0, IDD_EDITPROP, device);
  617.         free((char *)propitem);
  618.         WinSendMsg(hwnd, WM_INITDLG, MPFROMLONG(hwnd), MPFROMP(device));
  619.             load_string(IDS_TOPICPROP, szHelpTopic, sizeof(szHelpTopic));
  620.         return (MRESULT)TRUE;
  621.         case PROP_NEW:
  622.             load_string(IDS_TOPICEDITPROP, szHelpTopic, sizeof(szHelpTopic));
  623.         editpropname[0] = '\0';
  624.         WinDlgBox(HWND_DESKTOP, hwnd, EditPropDlgProc, 0, IDD_EDITPROP, device);
  625.         free((char *)propitem);
  626.         WinSendMsg(hwnd, WM_INITDLG, MPFROMLONG(hwnd), MPFROMP(device));
  627.             load_string(IDS_TOPICPROP, szHelpTopic, sizeof(szHelpTopic));
  628.         return (MRESULT)TRUE;
  629.         case ID_HELP:
  630.         get_help();
  631.         return (MRESULT)TRUE;
  632.         case DID_OK:
  633.             {PROFILE *prf;
  634. /* need to reopen profile file - this is wasteful */
  635.           if ( (prf = profile_open(szIniFile)) != (PROFILE *)NULL ) {
  636.             for (iprop=0; propitem[iprop].name[0]; iprop++) {
  637.             profile_write_string(prf, device, propitem[iprop].name, propitem[iprop].value);
  638.             }
  639.             strcpy(section, device);
  640.             strcat(section, " PageOffset");
  641.                 WinQueryWindowText(WinWindowFromID(hwnd, PROP_XOFFSET), sizeof(buf)-2, buf);
  642.             profile_write_string(prf, section, "X", buf);
  643.                 WinQueryWindowText(WinWindowFromID(hwnd, PROP_YOFFSET), sizeof(buf)-2, buf);
  644.             profile_write_string(prf, section, "Y", buf);
  645.             profile_close(prf);
  646.           }
  647.         }
  648.         free((char *)propitem);
  649.         WinDismissDlg(hwnd, DID_OK);
  650.                 return (MRESULT)TRUE;
  651.         case DID_CANCEL:
  652.         free((char *)propitem);
  653.         WinDismissDlg(hwnd, DID_CANCEL);
  654.         return (MRESULT)TRUE;
  655.     }
  656.     break;
  657.     }
  658.     return WinDefDlgProc(hwnd, msg, mp1, mp2);
  659. }
  660.  
  661.  
  662. char *device_queue_list;
  663. int device_to_file;
  664. int device_queue_index;
  665.  
  666.  
  667. /* dialog box for selecting printer device and resolution */
  668. MRESULT EXPENTRY
  669. DeviceDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  670. {
  671.     char buf[128];
  672.     int idevice;
  673.     int i, j;
  674.     char *p;
  675.     char *res;
  676.     int numentry;
  677.     char entry[MAXSTR];
  678.     struct prop_item_s *proplist;
  679.  
  680.     switch (msg) {
  681.     case WM_INITDLG:
  682.         /* fill in device, resolution list boxes */
  683.         p = get_devices();
  684.         res = p;    /* save for free() */
  685.         idevice = 0;
  686.         for (numentry=0; p!=(char *)NULL && strlen(p)!=0; numentry++) {
  687.             WinSendMsg( WinWindowFromID(hwnd, DEVICE_NAME),
  688.                 LM_INSERTITEM, MPFROMLONG(LIT_END), MPFROMP(p) );
  689.         if (strcmp(p, option.device_name) == 0)
  690.             idevice = numentry;
  691.             p += strlen(p) + 1;
  692.         }
  693.         free(res);
  694.         WinSendMsg( WinWindowFromID(hwnd, DEVICE_NAME),
  695.             LM_SELECTITEM, MPFROMLONG(idevice), MPFROMLONG(TRUE) );
  696.         /* force update of DEVICE_RES */
  697.         WinSendMsg(hwnd, WM_CONTROL, MPFROM2SHORT(DEVICE_NAME, CBN_LBSELECT),
  698.             MPFROMLONG(WinWindowFromID(hwnd, DEVICE_NAME)));
  699.         i = (int)WinSendMsg( WinWindowFromID(hwnd, DEVICE_RES),
  700.                 LM_SEARCHSTRING, MPFROM2SHORT(LSS_CASESENSITIVE, LIT_FIRST),
  701.             MPFROMP(option.device_resolution) );
  702.         if ((i == LIT_ERROR) || (i == LIT_NONE))
  703.         i = 0;
  704.         WinSendMsg( WinWindowFromID(hwnd, DEVICE_RES),
  705.             LM_SELECTITEM, MPFROMLONG(i), MPFROMLONG(TRUE) );
  706.         /* fill in queue list box */
  707.         p = device_queue_list;
  708.         device_queue_index = 0;
  709.         i = 0;
  710.         while (*p) {
  711.         if ( strcmp(p, option.printer_port) == 0 )
  712.             device_queue_index = i;
  713.         p += strlen(p)+1; /* skip to queue comment */
  714.         if (*p) {
  715.             WinSendMsg( WinWindowFromID(hwnd, SPOOL_PORT),
  716.             LM_INSERTITEM, MPFROMLONG(LIT_END), MPFROMP(p));
  717.             p += strlen(p)+1;
  718.         }
  719.         i++;
  720.         }
  721.         /* fill in page list box */
  722.         if ( (doc != (PSDOC *)NULL) && (doc->numpages != 0)) {
  723.         page_list.current = psfile.pagenum-1;
  724.         page_list.multiple = TRUE;
  725.         PageDlgProc(hwnd, msg, mp1, mp2);
  726.         }
  727.         else {
  728.         page_list.multiple = FALSE;
  729.         WinEnableWindow(WinWindowFromID(hwnd, PAGE_ALL), FALSE);
  730.         WinEnableWindow(WinWindowFromID(hwnd, PAGE_ODD), FALSE);
  731.         WinEnableWindow(WinWindowFromID(hwnd, PAGE_EVEN), FALSE);
  732.             WinSendMsg( WinWindowFromID(hwnd, PAGE_LIST),
  733.                 LM_INSERTITEM, MPFROMLONG(LIT_END), MPFROMP("All") );
  734.         WinEnableWindow(WinWindowFromID(hwnd, PAGE_LIST), FALSE);
  735.         }
  736.         /* set Print to File check box */
  737.         if (device_to_file) {
  738.             WinSendMsg( WinWindowFromID(hwnd, SPOOL_TOFILE),
  739.                 BM_SETCHECK, MPFROMLONG(1), MPFROMLONG(0));
  740.         WinEnableWindow(WinWindowFromID(hwnd, SPOOL_PORT), FALSE);
  741.         }
  742.         else {
  743.         WinSendMsg( WinWindowFromID(hwnd, SPOOL_PORT),
  744.             LM_SELECTITEM, MPFROMLONG(device_queue_index), MPFROMLONG(TRUE) );
  745.         }
  746.         break;
  747.         case WM_CONTROL:
  748.         if (mp1 == MPFROM2SHORT(DEVICE_NAME, CBN_LBSELECT)) {
  749.         idevice = (int)WinSendMsg(WinWindowFromID(hwnd, DEVICE_NAME), LM_QUERYSELECTION, (MPARAM)0, (MPARAM)0);
  750.         if (idevice == LIT_NONE)
  751.             return FALSE;
  752.         WinSendMsg(WinWindowFromID(hwnd, DEVICE_NAME), LM_QUERYITEMTEXT,  MPFROM2SHORT(idevice, sizeof(entry)), MPFROMP(entry));
  753.         if ( (proplist = get_properties(entry)) != (struct prop_item_s *)NULL ) {
  754.                 free((char *)proplist);
  755.             WinEnableWindow(WinWindowFromID(hwnd, DEVICE_PROP), TRUE);
  756.         }
  757.         else
  758.             WinEnableWindow(WinWindowFromID(hwnd, DEVICE_PROP), FALSE);
  759.         /* now look up entry in gvpm.ini */
  760.         /* and update DEVICE_RES list box */
  761.         {PROFILE *prf;
  762. /* need to reopen profile file - this is wasteful */
  763.           if ( (prf = profile_open(szIniFile)) != (PROFILE *)NULL ) {
  764.             profile_read_string(prf, DEVSECTION, entry, "", buf, sizeof(buf)-2);
  765.             profile_close(prf);
  766.           }
  767.           else
  768.             buf[0] = '\0';
  769.         }
  770.             while ((*buf) && (buf[strlen(buf)-1]==' '))
  771.             buf[strlen(buf)-1] = '\0';    /* remove trailing spaces */
  772.         buf[strlen(buf)+1] = '\0';    /* double NULL at end */
  773.         WinSendMsg(WinWindowFromID(hwnd, DEVICE_RES), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
  774.         p = buf;
  775.         if (*p == '\0') {
  776.             /* no resolutions can be set */
  777.             WinEnableWindow(WinWindowFromID(hwnd, DEVICE_RES), FALSE);
  778.             WinEnableWindow(WinWindowFromID(hwnd, DEVICE_RESTEXT), FALSE);
  779.         }
  780.         else {
  781.           WinEnableWindow(WinWindowFromID(hwnd, DEVICE_RES), TRUE);
  782.           WinEnableWindow(WinWindowFromID(hwnd, DEVICE_RESTEXT), TRUE);
  783.           while (*p!='\0') {
  784.             res = p;
  785.             while ((*p!='\0') && (*p!=','))
  786.             p++;
  787.             *p++ = '\0';
  788.                 WinSendMsg( WinWindowFromID(hwnd, DEVICE_RES),
  789.                     LM_INSERTITEM, MPFROMLONG(LIT_END), MPFROMP(res) );
  790.           }
  791.         }
  792.             WinSendMsg( WinWindowFromID(hwnd, DEVICE_RES),
  793.                 LM_SELECTITEM, MPFROMLONG(0), MPFROMLONG(TRUE) );
  794.         if ((int)WinSendMsg(WinWindowFromID(hwnd, DEVICE_RES), LM_QUERYSELECTION, (MPARAM)0, (MPARAM)0)
  795.             != LIT_NONE)
  796.             WinSetWindowText(WinWindowFromID(hwnd, DEVICE_RES), buf);
  797.         }
  798.         switch (SHORT2FROMMP(mp1)) {
  799.         case LN_ENTER:
  800.             if (SHORT1FROMMP(mp1) == PAGE_LIST)
  801.             WinPostMsg(hwnd, WM_COMMAND, (MPARAM)DID_OK, MPFROM2SHORT(CMDSRC_OTHER, TRUE));
  802.             if (SHORT1FROMMP(mp1) == SPOOL_PORT)
  803.             WinPostMsg(hwnd, WM_COMMAND, (MPARAM)DID_OK, MPFROM2SHORT(CMDSRC_OTHER, TRUE));
  804.             break;
  805.         case BN_CLICKED:
  806.            if (SHORT1FROMMP(mp1) == SPOOL_TOFILE) {
  807.             i = (int)WinSendMsg( WinWindowFromID(hwnd, SPOOL_TOFILE),
  808.                     BM_QUERYCHECK, MPFROMLONG(0), MPFROMLONG(0));
  809.             /* toggle state */
  810.             i = (i == 0) ? 1 : 0;
  811.             WinSendMsg( WinWindowFromID(hwnd, SPOOL_TOFILE),
  812.                 BM_SETCHECK, MPFROMLONG(i), MPFROMLONG(0));
  813.             if (i) {  /* save selection */
  814.                 device_queue_index = (int)WinSendMsg(WinWindowFromID(hwnd, SPOOL_PORT), 
  815.                 LM_QUERYSELECTION, (MPARAM)0, (MPARAM)0);
  816.             }
  817.             WinSendMsg( WinWindowFromID(hwnd, SPOOL_PORT),
  818.                 LM_SELECTITEM, MPFROMLONG(device_queue_index), 
  819.                 MPFROMLONG(i ? FALSE : TRUE));
  820.             WinEnableWindow(WinWindowFromID(hwnd, SPOOL_PORT), 
  821.                 (i ? FALSE : TRUE) );
  822.             
  823.            }
  824.            break;
  825.         }
  826.         break;
  827.     case WM_COMMAND:
  828.         switch(LOUSHORT(mp1)) {
  829.         case DID_OK:
  830.             /* save device name and resolution */
  831.             WinQueryWindowText(WinWindowFromID(hwnd, DEVICE_NAME), 
  832.              sizeof(option.device_name), option.device_name);
  833.             WinQueryWindowText(WinWindowFromID(hwnd, DEVICE_RES), 
  834.             sizeof(option.device_resolution), option.device_resolution);
  835.             /* get Print to File state */
  836.                 device_to_file = (int)WinSendMsg( WinWindowFromID(hwnd, SPOOL_TOFILE),
  837.                     BM_QUERYCHECK, MPFROMLONG(0), MPFROMLONG(0));
  838.             if (!device_to_file) {
  839.             /* save queue name */
  840.             device_queue_index = 1+(int)WinSendMsg(WinWindowFromID(hwnd, SPOOL_PORT), 
  841.                 LM_QUERYSELECTION, (MPARAM)0, (MPARAM)0);
  842.             p = device_queue_list;
  843.             for (i=2; i<device_queue_index+device_queue_index && strlen(p)!=0; i++)
  844.                 p += strlen(p)+1;
  845.             strcpy(option.printer_port, p);
  846.             }
  847.             /* save pages numbers */
  848.                 if ( (doc != (PSDOC *)NULL) && (doc->numpages != 0))
  849.                 PageDlgProc(hwnd, msg, mp1, mp2);
  850.             WinDismissDlg(hwnd, DID_OK);
  851.                     return (MRESULT)TRUE;
  852.             case ID_HELP:
  853.             get_help();
  854.             return (MRESULT)TRUE;
  855.         case PAGE_ALL:
  856.         case PAGE_EVEN:
  857.         case PAGE_ODD:
  858.             return (MRESULT)PageDlgProc(hwnd, msg, mp1, mp2);
  859.         case DEVICE_PROP:
  860.             idevice = (int)WinSendMsg(WinWindowFromID(hwnd, DEVICE_NAME), 
  861.             LM_QUERYSELECTION, (MPARAM)0, (MPARAM)0);
  862.             if (idevice == LIT_NONE)
  863.                 return (MRESULT)TRUE;
  864.             WinSendMsg(WinWindowFromID(hwnd, DEVICE_NAME), LM_QUERYITEMTEXT,  MPFROM2SHORT(idevice, sizeof(entry)), MPFROMP(entry));
  865.             if ( (proplist = get_properties(entry)) != (struct prop_item_s *)NULL ) {
  866.                     free((char *)proplist);
  867.                 load_string(IDS_TOPICPROP, szHelpTopic, sizeof(szHelpTopic));
  868.                     WinDlgBox(HWND_DESKTOP, hwnd, PropDlgProc, 0, IDD_PROP, entry);
  869.                 load_string(IDS_TOPICPRINT, szHelpTopic, sizeof(szHelpTopic));
  870.             }
  871.             else
  872.                 play_sound(SOUND_ERROR);
  873.             return (MRESULT)TRUE;
  874.         }
  875.         break;
  876.     }
  877.     return WinDefDlgProc(hwnd, msg, mp1, mp2);
  878. }
  879.  
  880. int
  881. get_device(int to_file)
  882. {
  883. int result;
  884.     device_to_file = to_file;
  885.     if ((device_queue_list= malloc(PRINT_BUF_SIZE)) == (char *)NULL)
  886.     return FALSE;
  887.     get_ports(device_queue_list, PRINT_BUF_SIZE);
  888.     load_string(IDS_TOPICPRINT, szHelpTopic, sizeof(szHelpTopic));
  889.     result = WinDlgBox(HWND_DESKTOP, hwnd_frame, DeviceDlgProc, 0, IDD_DEVICE, NULL);
  890.     free(device_queue_list);
  891.     if (result != DID_OK)
  892.     return FALSE;
  893.     return TRUE;
  894. }
  895.  
  896. /* print a range of pages using a Ghostscript device */
  897. void
  898. gsview_print(BOOL to_file)
  899. {
  900.     int flag;
  901.     char command[MAXSTR+MAXSTR];
  902.     
  903.     if (psfile.name[0] == '\0') {
  904.         gserror(IDS_NOTOPEN, NULL, MB_ICONEXCLAMATION, SOUND_NOTOPEN);
  905.         return;
  906.     }
  907.     
  908.     if (!get_device(to_file))
  909.         return;
  910.  
  911.     if (!gsview_cprint(device_to_file, printer.psname, printer.optname))
  912.         return;
  913.  
  914.     info_wait(IDS_WAITPRINT);
  915.  
  916.     sprintf(command,"%s @%s", option.gsother, printer.optname);
  917.  
  918.     if (strlen(command) > MAXSTR-1) {
  919.         /* command line too long */
  920.         gserror(IDS_TOOLONG, command, MB_ICONHAND, SOUND_ERROR);
  921.             if (!debug)
  922.             unlink(printer.psname);
  923.             printer.psname[0] = '\0';
  924.         if (!debug)
  925.             unlink(printer.optname);
  926.         printer.optname[0] = '\0';
  927.         return;
  928.     }
  929.  
  930.     flag = exec_pgm(option.gsexe, command, FALSE, &printer.prog);
  931.     if (!flag || !printer.prog.valid) {
  932.             cleanup_pgm(&printer.prog);
  933.         gserror(IDS_CANNOTRUN, command, MB_ICONHAND, SOUND_ERROR);
  934.         if (!debug)
  935.             unlink(printer.psname);
  936.         printer.psname[0] = '\0';
  937.             if (!debug)
  938.             unlink(printer.optname);
  939.             printer.optname[0] = '\0';
  940.         info_wait(IDS_NOWAIT);
  941.         return;
  942.     }
  943.  
  944.     info_wait(IDS_NOWAIT);
  945.     
  946.     return;
  947. }
  948.  
  949.